package com.fugit.servlet;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.imgscalr.Scalr;
import org.json.JSONArray;
import org.json.JSONObject;



/**
 * Upload file servlet.
 * 
 * @author Jee3
 * 
 */
public class UploadServlet extends HttpServlet {

	/**
	 * serialVersionUID.
	 */
	private static final long serialVersionUID = -1259576023339270135L;

	/**
	 * Log4J the logger.
	 */
	private static final Logger LOG = Logger.getLogger(UploadServlet.class);

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doGet(
	 * javax.servlet.http.HttpServletRequest ,
	 * javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected final void doGet(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {

		LOG.error(request.getServletContext().getRealPath("/"));
		if (request.getParameter("getfile") != null
				&& !request.getParameter("getfile").isEmpty()) {
			final File file = new File(request.getServletContext()
					.getRealPath("/")
					+ "uploads/"
					+ request.getParameter("getfile"));
			if (file.exists()) {
				int bytes;
				final ServletOutputStream outputStream = response
						.getOutputStream();

				response.setContentType(getMimeType(file));
				response.setContentLength((int) file.length());
				response.setHeader("Content-Disposition",
						"inline; filename=\"" + file.getName() + "\"");
				final byte[] bbuf = new byte[1024];
				final DataInputStream inputStream = new DataInputStream(
						new FileInputStream(file));

				while ((inputStream != null)
						&& ((bytes = inputStream.read(bbuf)) != -1)) {
					outputStream.write(bbuf, 0, bytes);
				}

				inputStream.close();
				outputStream.flush();
				outputStream.close();
			}
		} else if (request.getParameter("delfile") != null
				&& !request.getParameter("delfile").isEmpty()) {
			final File file = new File(request.getServletContext()
					.getRealPath("/")
					+ "uploads/"
					+ request.getParameter("delfile"));
			if (file.exists()) {
				file.delete(); // TODO:check and report success
			}
		} else if (request.getParameter("getthumb") != null
				&& !request.getParameter("getthumb").isEmpty()) {
			final File file = new File(request.getServletContext()
					.getRealPath("/")
					+ "uploads/"
					+ request.getParameter("getthumb"));
			if (file.exists()) {
				LOG.debug(file.getAbsolutePath());
				final String mimetype = getMimeType(file);
				if (mimetype.endsWith("png") || mimetype.endsWith("jpeg")
						|| mimetype.endsWith("jpg")
						|| mimetype.endsWith("gif")) {
					final BufferedImage bufferedImage = ImageIO.read(file);
					if (bufferedImage != null) {
						final BufferedImage thumb = Scalr.resize(
								bufferedImage, 75);
						final ByteArrayOutputStream outputStream = 
								new ByteArrayOutputStream();
						if (mimetype.endsWith("png")) {
							ImageIO.write(thumb, "PNG", outputStream);
							response.setContentType("image/png");
						} else if (mimetype.endsWith("jpeg")) {
							ImageIO.write(thumb, "jpg", outputStream);
							response.setContentType("image/jpeg");
						} else if (mimetype.endsWith("jpg")) {
							ImageIO.write(thumb, "jpg", outputStream);
							response.setContentType("image/jpeg");
						} else {
							ImageIO.write(thumb, "GIF", outputStream);
							response.setContentType("image/gif");
						}
						final ServletOutputStream srvos = response
								.getOutputStream();
						response.setContentLength(outputStream.size());
						response.setHeader("Content-Disposition",
								"inline; filename=\"" + file.getName() + "\"");
						outputStream.writeTo(srvos);
						srvos.flush();
						srvos.close();
					}
				}
			} // TODO: check and report success
		} else {
			final PrintWriter writer = response.getWriter();
			writer.write("call POST with multipart form data");
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doPost(
	 * javax.servlet.http.HttpServletRequest ,
	 * javax.servlet.http.HttpServletResponse)
	 */
	@SuppressWarnings("unchecked")
	@Override
	protected final void doPost(final HttpServletRequest request,
			final HttpServletResponse response) throws ServletException,
			IOException {

		if (!ServletFileUpload.isMultipartContent(request)) {
			throw new IllegalArgumentException(
					"Request is not multipart, please"
							+ " 'multipart/form-data' enctype for your form.");
		}

		final ServletFileUpload uploadHandler = new ServletFileUpload(
				new DiskFileItemFactory());
		final PrintWriter writer = response.getWriter();
		response.setContentType("application/json");
		final JSONArray json = new JSONArray();
		try {
			final List<FileItem> items = uploadHandler.parseRequest(request);
			for (FileItem item : items) {
				if (!item.isFormField()) {

					final File file = new File(request.getServletContext()
							.getRealPath("/") + "uploads/", item.getName());
					item.write(file);
					final JSONObject jsono = new JSONObject();
					jsono.put("name", item.getName());
					jsono.put("size", item.getSize());
					jsono.put("url",
							"UploadServlet?getfile=" + item.getName());

					// Put filename in Server session
					final HttpSession session = request.getSession();
					session.setAttribute("fileName", item.getName());

					
					jsono.put("thumbnail_url", "UploadServlet?getthumb="
							+ item.getName());
					jsono.put("delete_url",
							"UploadServlet?delfile=" + item.getName());
					jsono.put("delete_type", "GET");
					json.put(jsono);
					LOG.debug(json.toString());
				}
			}
		} catch (FileUploadException e) {
			LOG.error("error in File Upload", e);
		} catch (Exception e) {
			LOG.error("error in File Upload", e);
		} finally {
			writer.write(json.toString());
			writer.close();
		}

	}

	/**
	 * @param file
	 *            the File
	 * @return the MIME Type
	 */
	private String getMimeType(final File file) {
		String mimetype;
		if (file.exists()) {
			if (getSuffix(file.getName()).equalsIgnoreCase("png")) {
				mimetype = "image/png";
			} else if (getSuffix(file.getName()).equalsIgnoreCase("jpg")) {
				mimetype = "image/jpg";
			} else if (getSuffix(file.getName()).equalsIgnoreCase("jpeg")) {
				mimetype = "image/jpeg";
			} else if (getSuffix(file.getName()).equalsIgnoreCase("gif")) {
				mimetype = "image/gif";
			} else {
				final javax.activation.MimetypesFileTypeMap mtMap = 
						new javax.activation.MimetypesFileTypeMap();
				mimetype = mtMap.getContentType(file);
			}
		} else {
			mimetype = "";
		}
		return mimetype;
	}

	/**
	 * @param filename
	 *            the filename
	 * @return the suffix
	 */
	private String getSuffix(final String filename) {
		String suffix;
		final int pos = filename.lastIndexOf('.');
		if (pos > 0 && pos < filename.length() - 1) {
			suffix = filename.substring(pos + 1);
		} else {
			suffix = "";
		}
		return suffix;
	}
}